﻿using System;
using UnityEngine;

[Serializable]
public class USInternalKeyframe : ScriptableObject
{
    [SerializeField]
    private bool brokenTangents;
    [SerializeField]
    public USInternalCurve curve;
    [SerializeField]
    private float inTangent;
    [SerializeField]
    private float outTangent;
    [SerializeField]
    private float time;
    [SerializeField]
    private float value;

    public void ConvertFrom(Keyframe keyframe)
    {
        this.value = keyframe.value;
        this.time = keyframe.time;
        this.inTangent = keyframe.inTangent;
        this.outTangent = keyframe.outTangent;
    }

    public void Flatten()
    {
        if (this.curve != null)
        {
            this.inTangent = 0f;
            this.outTangent = 0f;
            this.curve.BuildAnimationCurveFromInternalCurve();
        }
    }

    public void LeftTangentConstant()
    {
        this.inTangent = float.PositiveInfinity;
        this.curve.BuildAnimationCurveFromInternalCurve();
    }

    public void LeftTangentLinear()
    {
        if (this.curve != null)
        {
            USInternalKeyframe prevKeyframe = this.curve.GetPrevKeyframe(this);
            if (prevKeyframe != null)
            {
                this.inTangent = (prevKeyframe.value - this.value) / (prevKeyframe.time - this.time);
                this.brokenTangents = true;
                this.curve.BuildAnimationCurveFromInternalCurve();
            }
        }
    }

    public void RightTangentConstant()
    {
        this.outTangent = float.PositiveInfinity;
        this.curve.BuildAnimationCurveFromInternalCurve();
    }

    public void RightTangentLinear()
    {
        if (this.curve != null)
        {
            USInternalKeyframe nextKeyframe = this.curve.GetNextKeyframe(this);
            if (nextKeyframe != null)
            {
                this.outTangent = (nextKeyframe.value - this.value) / (nextKeyframe.time - this.time);
                this.brokenTangents = true;
                this.curve.BuildAnimationCurveFromInternalCurve();
            }
        }
    }

    public void Smooth()
    {
        if (this.curve != null)
        {
            int index = -1;
            for (int i = 0; i < this.curve.UnityAnimationCurve.keys.Length; i++)
            {
                Keyframe keyframe = this.curve.UnityAnimationCurve.keys[i];
                if (Mathf.Approximately(keyframe.time, this.time))
                {
                    index = i;
                }
                if (index != -1)
                {
                    break;
                }
            }
            if (index != -1)
            {
                this.curve.UnityAnimationCurve.SmoothTangents(index, 0f);
                this.curve.BuildInternalCurveFromAnimationCurve();
            }
        }
    }

    public bool BrokenTangents
    {
        get
        {
            return this.brokenTangents;
        }
        set
        {
            this.brokenTangents = value;
            if (this.curve != null)
            {
                this.curve.BuildAnimationCurveFromInternalCurve();
            }
        }
    }

    public float InTangent
    {
        get
        {
            return this.inTangent;
        }
        set
        {
            this.inTangent = value;
            if (this.curve != null)
            {
                this.curve.BuildAnimationCurveFromInternalCurve();
            }
        }
    }

    public float OutTangent
    {
        get
        {
            return this.outTangent;
        }
        set
        {
            this.outTangent = value;
            if (this.curve != null)
            {
                this.curve.BuildAnimationCurveFromInternalCurve();
            }
        }
    }

    public float Time
    {
        get
        {
            return this.time;
        }
        set
        {
            this.time = value;
            if (this.curve != null)
            {
                this.time = Mathf.Min(Mathf.Max(0f, this.time), this.curve.Duration);
                this.curve.BuildAnimationCurveFromInternalCurve();
            }
        }
    }

    public float Value
    {
        get
        {
            return this.value;
        }
        set
        {
            this.value = value;
            if (this.curve != null)
            {
                this.curve.BuildAnimationCurveFromInternalCurve();
            }
        }
    }
}

